﻿
namespace TFSChangeLogCL.GeneralUtilities
{
    using System.Collections.Specialized;
    using System.Text.RegularExpressions;

    /// <summary>Summary description for <see cref="ArgumentParserHelper"/> class.</summary>
    public class ArgumentParserHelper
    {
        /// <summary>Summary description for class level field of type <c>System.Collections.Specialized.StringDictionary</c>.</summary>
        private StringDictionary Parameters;

        // Constructor

        /// <summary>Initializes a new instance of the <see cref="ArgumentParserHelper"/> class.</summary>
        /// <param name="Args">TODO: Summary description for <c>Args</c> parameter of type <c>string[]</c>.</param>
        public ArgumentParserHelper(string[] Args)
        {
            this.Parameters = new StringDictionary();
            Regex Spliter = new Regex(@"^-{1,2}|^/|=|:", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            Regex Remover = new Regex(@"^['""]?(.*?)['""]?$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            string Parameter = null;
            string[] Parts;

            // Valid parameters forms:
            // {-,/,--}param{ ,=,:}((",')value(",'))
            // Examples: -param1 value1 --param2 /param3:"Test-:-work" /param4=happy -param5 '--=nice=--'
            foreach (string Txt in Args)
            {
                // Look for new parameters (-,/ or --) and a possible enclosed value (=,:)
                Parts = Spliter.Split(Txt, 3);
                switch (Parts.Length)
                {
                    // Found a value (for the last parameter found (space separator))
                    case 1:
                        if (Parameter != null)
                        {
                            if (!this.Parameters.ContainsKey(Parameter))
                            {
                                Parts[0] = Remover.Replace(Parts[0], "$1");
                                this.Parameters.Add(Parameter, Parts[0]);
                            }

                            Parameter = null;
                        }

                        // else Error: no parameter waiting for a value (skipped)
                        break;

                    // Found just a parameter
                    case 2:
                        // The last parameter is still waiting. With no value, set it to true.
                        if (Parameter != null)
                        {
                            if (!this.Parameters.ContainsKey(Parameter))
                            {
                                this.Parameters.Add(Parameter, "true");
                            }
                        }

                        Parameter = Parts[1];
                        break;

                    // Parameter with enclosed value
                    case 3:
                        // The last parameter is still waiting. With no value, set it to true.
                        if (Parameter != null)
                        {
                            if (!this.Parameters.ContainsKey(Parameter))
                            {
                                this.Parameters.Add(Parameter, "true");
                            }
                        }

                        Parameter = Parts[1];

                        // Remove possible enclosing characters (",')
                        if (!this.Parameters.ContainsKey(Parameter))
                        {
                            Parts[2] = Remover.Replace(Parts[2], "$1");
                            this.Parameters.Add(Parameter, Parts[2]);
                        }

                        Parameter = null;
                        break;
                }
            }

            // In case a parameter is still waiting
            if (Parameter != null)
            {
                if (!this.Parameters.ContainsKey(Parameter))
                {
                    this.Parameters.Add(Parameter, "true");
                }
            }
        }

        // Retrieve a parameter value if it exists

        /// <summary>Gets the value for this.</summary>
        /// <param name="Param">TODO: Summary description for <c>Param</c> parameter of type <c>string</c>.</param>
        /// <returns>TODO: returns an object of type <c>string</c>.</returns>
        public string this[string Param]
        {
            get
            {
                return (this.Parameters[Param]);
            }
        }
    }
}
